package ferp.center.server.ranking;

import ferp.center.server.Action;
import ferp.center.server.entity.Range;
import ferp.center.server.entity.RangeTree;
import ferp.center.server.entity.Rating;

import javax.persistence.EntityManager;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;

/**
 * User: igorgok
 * Date: 6/2/13 5:55 PM
 */
public class Lookup
{
  static RangeTree tree(EntityManager em, String configuration)
  {
    return em.find(RangeTree.class, configuration);
  }

  static Range leaf(EntityManager em, RangeTree tree, Rating rating, LinkedList<Range> ancestors)
  {
    Range r = tree.getRoot(em);
    long value = rating.getValue();

    ancestors.addFirst(r);

    for (Range.Children children = r.children(); children.size() > 0; children = r.children())
    {
      long down = 0;

      for (Range.Child child : children.sorted())
        if (value <= child.max)
          down = child.key;
        else
          break;

      if (down == 0)
        return null;

      // step down
      Range child = em.find(Range.class, down);

      if (child == null)
      {
        Action.logger().log(Level.SEVERE, "lookup leaf failed for child " + r.getKey() + " at level " + r.getLevel());

        // update r's children
        children.remove(down);
        r.update(children);

        return null;
      }

      r = child;
      ancestors.addFirst(r);
    }

    Range first = ancestors.getFirst();

    if (first.getLevel() == 0)
    {
      ancestors.removeFirst();

      return first.getMax() == value ? first : null;
    }

    return null;
  }

  @SuppressWarnings("unchecked")
  public static List<Rating> ratings(EntityManager em, Range leaf)
  {
    return em.createQuery("SELECT r FROM Rating r WHERE r.range = ?1").setParameter(1, leaf.getKey()).getResultList();
  }
}
